package com.roadjava.rbac.controller;

import com.alibaba.excel.EasyExcel;
import com.roadjava.rbac.bean.entity.UserDO;
import com.roadjava.rbac.bean.req.user.*;
import com.roadjava.rbac.bean.res.Result;
import com.roadjava.rbac.bean.vo.OnlineUserVO;
import com.roadjava.rbac.bean.vo.UserVO;
import com.roadjava.rbac.config.HoneyLogs;
import com.roadjava.rbac.enums.LogEnum;
import com.roadjava.rbac.security.RateLimitService;
import com.roadjava.rbac.service.DecryptionService;
import com.roadjava.rbac.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;


@RestController
@Slf4j
@Validated
@RequestMapping("/user")
public class UserController {
    @Resource
    private UserService userService;
    @Resource
    private DecryptionService decryptionService;


    // 引入 RateLimitService
    private final RateLimitService rateLimitService = new RateLimitService();

    @GetMapping("/queryById")
    public Result<UserVO> queryById(@NotNull Long id) {
        return Result.buildSuccess(userService.queryById(id));
    }

    @HoneyLogs(operation = "修改用户信息",type = LogEnum.UPDATE)
    @PostMapping("/modifyById")
    public Result<String> modifyById(@RequestBody @Validated UserUpdateReq updateReq) {
        String username = updateReq.getId().toString(); // 假设请求体中包含用户名
        if (!rateLimitService.isAllowed(username)) {
            return Result.buildFailure("请求过于频繁，请稍后再试。");
        }

        userService.modifyById(updateReq);
        return Result.buildSuccess("修改成功");
    }

    @HoneyLogs(operation = "修改密码",type = LogEnum.UPDATE)
    @PostMapping("/updatePwd")
    public Result<String> updatePwd(@RequestBody @Validated UpdatePwdReq updatePwdReq) {
        String username = updatePwdReq.getId().toString(); // 假设请求体中包含用户名
        String oldPwd = updatePwdReq.getOriginalPwd();
        String newPwd = updatePwdReq.getNewPwd();
        try {
            // 尝试解密原始密码和新密码
            oldPwd = decryptionService.decryptPassword(oldPwd);
            newPwd = decryptionService.decryptPassword(newPwd);
        } catch (Exception e) {
            // 捕获解密异常并返回错误信息
            return Result.buildFailure("密码解密失败: " + e.getMessage());
        }
        updatePwdReq.setOriginalPwd(oldPwd);
        updatePwdReq.setNewPwd(newPwd);
        if (!rateLimitService.isAllowed(username)) {
            return Result.buildFailure("请求过于频繁，请稍后再试。");
        }

        userService.updatePwd(updatePwdReq);
        return Result.buildSuccess("密码修改成功");
    }

    @HoneyLogs(operation = "添加用户",type = LogEnum.ADD)
    @PostMapping("/add")
    public Result<String> add(@RequestBody @Validated UserAddReq addReq) {
        String username = addReq.getUsername(); // 假设请求体中包含用户名
        if (!rateLimitService.isAllowed(username)) {
            return Result.buildFailure("请求过于频繁，请稍后再试。");
        }

        userService.add(addReq);
        return Result.buildSuccess("添加成功");
    }

    @HoneyLogs(operation = "注册用户",type = LogEnum.ADD)
    @PostMapping("/register")
    public Result<String> register(@RequestBody @Validated UserRegisterReq registerReq) {
        String username = registerReq.getUsername(); // 假设请求体中包含用户名
        String pwd = registerReq.getPwd();
        try {
            // 尝试解密原始密码和新密码
            pwd = decryptionService.decryptPassword(pwd);

        } catch (Exception e) {
            // 捕获解密异常并返回错误信息
            return Result.buildFailure("密码解密失败: " + e.getMessage());
        }
        registerReq.setPwd(pwd);
        if (!rateLimitService.isAllowed(username)) {
            return Result.buildFailure("请求过于频繁，请稍后再试。");
        }

        userService.register(registerReq);
        return Result.buildSuccess("注册成功");
    }

    @HoneyLogs(operation = "删除用户",type = LogEnum.DELETE)
    @DeleteMapping("/deleteById")
    public Result<String> deleteById(@NotNull Long id) {
        String username = id.toString(); // 从请求中获取用户名
        if (!rateLimitService.isAllowed(username)) {
            return Result.buildFailure("请求过于频繁，请稍后再试。");
        }

        userService.deleteById(id);
        return Result.buildSuccess("删除成功");
    }

    @HoneyLogs(operation = "分配角色",type = LogEnum.UPDATE)
    @PostMapping("/assignRole")
    public Result<String> assignRole(@RequestBody @Validated AssignRoleReq assignRoleReq) {
        String username = assignRoleReq.getUserId().toString(); // 假设请求体中包含用户名
        if (!rateLimitService.isAllowed(username)) {
            return Result.buildFailure("请求过于频繁，请稍后再试。");
        }

        userService.assignRole(assignRoleReq);
        return Result.buildSuccess("分配角色成功");
    }

    @PostMapping("/queryPage")
    public Result<List<UserVO>> queryPage(@RequestBody UserPageReq pageReq) {
        String username = pageReq.getUsername(); // 假设请求体中包含用户名
        if (!rateLimitService.isAllowed(username)) {
            return Result.buildFailure("请求过于频繁，请稍后再试。");
        }

        return userService.queryPage(pageReq);
    }

    @HoneyLogs(operation = "修改用户信息",type = LogEnum.UPDATE)
    @PostMapping("/update")
    public Result<String> updateUser(@RequestBody UserUpdateReq2 user) {
        userService.updateUserInfo(user);
        return Result.buildSuccess("更新成功"); // 返回成功的 Result
    }

    @PostMapping("/getRolebyUser/{id}")
    public ResponseEntity<Long> getRolebyUser(@PathVariable long id) {
        // 在这里进一步校验权限，如果需要的话
        Long roleId = userService.postRoleByUser(id);

        if (roleId != null) {
            return ResponseEntity.ok(roleId); // 返回 200 OK 和角色 ID
        } else {
            return ResponseEntity.status(HttpStatus.NOT_FOUND) // 返回 404 NOT FOUND
                    .body(null); // 返回 null
        }
    }

    /**
     * 导出
     *
     * @param response 响应对象
     * @param user
    查询对象
     * @throws IOException
     */
    @HoneyLogs(operation = "导出用户信息",type = LogEnum.EXPORT)
    @GetMapping("/exportExcel")
    public void exportExcel(HttpServletResponse response, UserDO user) throws
            IOException {
        // 设置响应头
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
                response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("用户信息", "UTF-8").replaceAll("\\+",
                "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" +
                fileName + ".xlsx");
        // 查询列表数据
        List<UserDO> list = userService.getList(user);
        // 导出数据
        EasyExcel.write(response.getOutputStream(), UserDO.class).sheet("用户信息").doWrite(list);
    }
    //查找在线用户
    @GetMapping("/selectOnlineUser")
    public ResponseEntity<List<OnlineUserVO>> selectOnlineUser() throws IOException {
        List<OnlineUserVO> onlineUsers = new ArrayList<>();

        List<OnlineUserVO> onlineUserVOS = userService.queryUserOnline();

        return ResponseEntity.ok(onlineUserVOS);


    }




}
